iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0

Annotation 要怎麼定義會影響使用這個 library 的使用者體驗,annotation 必須要好理解而且還要具有可擴充性。我們的目標是要方便使用者獲取 RSS 格式裡面的資料,所以我們可以就資料層面來看這件事情。在 RSS 格式裡,有三個重要的元素:

  1. Tag:像是 <title> 這種東西,他除了有許多不同的 tag ,也可能有自訂的 tag 。
  2. Attribute:Tag 內的屬性 <title attr="Attribute"> ,這個也能夠自定義。
  3. value:被 tag 夾起來的值,像是 <title>This is a value</title>

透過從資料中拆解出這三個元素,我們可以設計三個 annotation 去分別定義這三個資料型態。透過 Kotlin 的 data class 和 annotation ,我們可以組合出許多自定義的資料。這三個資料型態分別又對應了...

  1. @RssTag
  2. @RssAttribute
  3. @RssValue

假如現在使用者有個需求是不同的 tag 想要擺在 Kotlin data class 的同一個變數或是 property 底下,那這三個 annotation 可能都無法滿足這個需求,因為以上這三個都是只能處理單個 tag 或是 單個值。因此,我們需要設計一個 annotation 讓使用者可以把不同 tag 的資料按優先順序放到指定的 data class 裡面,那個 annotation 就是 @RssRawData

讓我們來看看對應的資料會長怎麼樣吧!假設我們有一個 RSS 的資料:

<channel customAttr="attr">
    <title>the title</title>
		<itunes:title>itunes title</itunes:title>
    <googleplay:description>google play desc</googleplay:description>
    <itunes:summary>itunes author</itunes:summary>
</channel>

使用 annotation 可以對應成一個 data class。

@RssTag(name = "channel")
data class CustomChannelData(
		@RssAttribute(name="customAttr")
		val customAttribute: String?,
    @RssTag(name="title",order = [OrderType.GOOGLE, OrderType.ITUNES, OrderType.RSS_STANDARD])
    val rssTitle: String?,
    @RssRawData(["itunes:summary", "googleplay:description", "googleplay:summary"])
    val description: String?,
)

我們可以看到在這邊我們指定要爬一個叫 channel 的 tag ,然後把 customAttr 透過 @RssAttribute 放到 customAttribute 的 class property 裡面。 rssTitle 裡面想依序取資料的有 google 、itunes 和 RSS 標準格式,所以 google 平台格式沒取到值才會往下個優先順序去取,依此類推。這個順序的設計可以確保使用者的 rssTitle 可以盡最大可能拿到可用的值。 @RssRawData 也有一樣的設計概念,只是它不限於三大平台格式,使用者塞幾個,他就會依照那個陣列的順序去取值,取不到就會往下一個找,另外, @RssRawData 裡面的字串陣列就是使用者想要取值的候選名單,這個名稱可以隨意自訂。像是上方範例裡面有 ["itunes:summary", "googleplay:description", "googleplay:summary"] ,代表依序尋找和取值放在 description 這個 property 裡面。如此一來,我們可以確保使用者有多個 annotation 對應不同種的情況,也有一個 @RssRawData 專門處理特殊的客製化 tag 需求!


上一篇
Annotation in Kotlin
下一篇
Annotation Processor 的運作
系列文
如何使用 Kotlin Annotation Processor 做出自己的 Custom Data Parser Library30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言